home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-04-10 | 18.1 KB | 662 lines | [TEXT/MPS ] |
- /*
- copyright © 1992-1994 Apple Computer Inc. All rights reserved.
-
- OldApp.c
- This file implements old application message overrides for the specific driver.
-
- Included in this file is the old PrintRecord emulation. Note that the ImageWriter
- PrintRecord is a wonder of misdirection and special cases. You'll have fun
- figuring out the code - so unless you really want to exactly emulate the ImageWriter
- pages, you shouldn't spend too much time looking at this code.
-
- Modification history
- 7/23/92 TED New file today
- 12/20/93 dmh Sync'd with the shipping 1.0b3 GX driver.
- 8/26/94 dmh Sync'd with the shipping 1.0.1 GX driver.
-
- */
-
- // Include the standard Mac header files
- #include <Errors.h>
- #include <ToolUtils.h>
- #include <StdIO.h>
- #include <StdLib.h>
- #include <String.h>
- #include <Strings.h>
- #include <Resources.h>
- #include <ToolUtils.h>
- #include <OSUtils.h>
- #include <Files.h>
- #include <Types.h>
- #include <Packages.h>
- #include <Memory.h>
- #include <Serial.h>
- #include <Devices.h>
- #include <Fonts.h>
- #include <Printing.h>
- #include <Script.h>
- #include <Events.h>
- #include <Dialogs.h>
- #include <FixMath.h>
- #include <Lists.h>
- #include <AppleTalk.h>
- #include <Menus.h>
- #include <Events.h>
- #include <Balloons.h>
- #include <Folders.h>
- #include <SCSI.h>
-
- // Include the new QuickDraw GX graphics header files
- #include <graphics routines.h>
- #include <graphics libraries.h>
- #include <math routines.h>
- #include <qd library.h>
- #include <font library.h>
- #include <layout routines.h>
- #include <graphics libraries.h>
-
- // Include the required Printing Manager header files
- #include <PrintingManager.h>
- #include <PrintingMessages.h>
- #include <PrintingDrivers.h>
- #include <Collections.h>
- #include <Messages.h>
- #include <PrintingResTypes.h>
- #include <PrintingErrors.h>
- #include <PrintingLibraries.h>
-
- #include <GXExceptions.h>
-
- #include "CommonDefines.h" // things common to .r and .h files
-
- /* ---------------------------------------------------------------------------- */
- /* INTERNAL TYPEDEFS AND STRUCTURES */
- /* ---------------------------------------------------------------------------- */
- // ImageWriter wDev values
- #define kBest 0x01
- #define kPortrait 0x02
- #define kTallAdjusted 0x04
- #define k50Percent 0x08
- #define kNoGaps 0x10
- #define kSetResCalled 0x20
-
- // some ImageWriter constants
- #define kGapSize 60 // gap at top of page in 120ths of an inch
- #define kSmallPlaten 16 // platen width in half inches for small IW
- #define kBigPlaten 27 // platen width in half inches for the 15" IW
-
- /* ---------------------------------------------------------------------------- */
- /* FORWARD DECLARES */
- /* ---------------------------------------------------------------------------- */
- OSErr SD_ConvertPrintRecordTo(THPrint hoPrint);
- OSErr SD_ConvertPrintRecordFrom(gxUniversalPrintRecordHdl huPrint);
-
-
- /* ---------------------------------------------------------------------------- */
- /* INTERNAL ROUTINES */
- /* ---------------------------------------------------------------------------- */
- OSErr UpdatePrintRecord(THPrint hPrint)
- {
- OSErr anErr;
- gxUniversalPrintRecordHdl huPrint = hPrint;
- gxUniversalPrintRecordPtr puPrint;
- short devVRes, devHRes, appVRes, appHRes;
- short cPlaten;
-
- // convert to universal format
- anErr = SD_ConvertPrintRecordTo(hPrint);
- if (anErr == noErr)
- {
- // determine application & device resolutions, based upon quality mode, tall adjusted
- // setting, and if the app called SetRsl:
- // draft - 80(h)*72(v)
- // faster - 80(h)*72(v)
- // best - 160(h)*144(v)
- //
- // draft (tall adjusted) - 72*72
- // faster (tall adjusted) - 72*72
- // best (tall adjusted) - 144*144
-
- puPrint = *huPrint;
- if (puPrint->options & gxPreciseBitmap)
- switch(puPrint->qualityMode)
- {
- case gxDraftQuality:
- case gxFasterQuality:
- devVRes = devHRes = 72;
- appVRes = appHRes = 72;
- break;
-
- case gxBestQuality:
- devVRes = devHRes = 144;
- appVRes = appHRes = 72;
- break;
- }
- else
- switch(puPrint->qualityMode)
- {
- case gxDraftQuality:
- case gxFasterQuality:
- appVRes = devVRes = 72;
- appHRes = devHRes = 80;
- break;
-
- case gxBestQuality:
- devVRes = 144;
- devHRes = 160;
- appVRes = 72;
- appHRes = 80;
- break;
- }
-
- // SetRsl was called? Use the resolution specified by the application
- if (puPrint->appVRes != 72)
- {
- appVRes = devVRes = puPrint->appVRes;
- appHRes = devHRes = puPrint->appHRes;
- }
-
- // finally, store the app & device resolutions
- puPrint->devVRes = devVRes;
- puPrint->devHRes = devHRes;
- puPrint->appVRes = appVRes;
- puPrint->appHRes = appHRes;
-
- // here we do page size calculations
- // Please note that this code is confusing - it's purpose is to emulate
- // the existing ImageWriter driver's page size. Most drivers would not
- // do this - the existing in the system probably is good enough.
- {
- long pageGap; // gap at top of page
- long dvPaper, dhPaper; // paper size at device res
- long dvPage, dhPage; // page size at device res
- long scanLines, scanBits; // # of scan lines or bits on page
- long maxH; // maximum width
- long hOff, vOff; // margins (horiz & vert) to get paper rect from page rect
-
- // gap at the top of the page in pixels
- pageGap = (kGapSize * appVRes) / 120;
- if (puPrint->options & gxBiggerPages)
- pageGap = 0;
-
- // figure out paper size in application space pixels
- dvPaper = (puPrint->pageV * appVRes) / 120;
- dhPaper = (puPrint->pageH * appHRes) / 120;
-
- // vertically, align to the head height of 8 pixels
- scanLines = ((dvPaper - pageGap) >> 3) << 3;
-
- // horizontally, allow the biggest width we can handle
- cPlaten = kSmallPlaten;
- if (puPrint->pageH > (9*120) )
- cPlaten = kBigPlaten;
-
- maxH = (cPlaten * appHRes) >> 1;
- if (maxH > dhPaper)
- maxH = dhPaper;
- scanBits = (maxH >> 4) << 4;
-
- if (puPrint->orientation == gxPortraitOrientation)
- {
- // portrait
-
- dhPage = scanBits;
- dvPage = scanLines;
-
- hOff = (dhPage - dhPaper) >> 1;
- vOff = -pageGap;
- }
- else
- {
- // landscape
-
- dhPage = scanLines;
- dvPage = scanBits;
-
- // reverse the paper definition as well
- {
- long iTemp = dhPaper;
- dhPaper = dvPaper;
- dvPaper = iTemp;
- }
-
- hOff = -pageGap;
- vOff = (dvPage - dvPaper) >> 1;
- }
-
- // 50% reduction? scale everything by 2X
- if (puPrint->options & gxUserFlag0)
- {
- dhPage <<= 1;
- dvPage <<= 1;
- dhPaper <<= 1;
- dvPaper <<= 1;
- hOff <<= 1;
- vOff <<= 1;
- }
-
- // set the page and paper in app space
- puPrint->appPage.left = puPrint->appPage.top = 0;
- puPrint->appPage.right = dhPage;
- puPrint->appPage.bottom = dvPage;
-
- puPrint->appPaper.left = hOff;
- puPrint->appPaper.top = vOff;
- puPrint->appPaper.right = dhPaper + hOff;
- puPrint->appPaper.bottom = dvPaper + vOff;
-
- // from page, scale up to device space (in case some weenie decides to look at that)
- puPrint->devPage.left = puPrint->devPage.top = 0;
- puPrint->devPage.right = dhPage * devHRes / appHRes;
- puPrint->devPage.bottom = dvPage * devVRes / appVRes;
- }
-
- // convert back to non-universal format
- anErr = SD_ConvertPrintRecordFrom((gxUniversalPrintRecordHdl) hPrint);
- }
-
- return(anErr);
-
- } // UpdatePrintRecord
-
- //<FF>
- /* ---------------------------------------------------------------------------- */
- /* MESSAGE OVERRIDES */
- /* ---------------------------------------------------------------------------- */
- OSErr SD_ConvertPrintRecordTo(THPrint hoPrint)
- /*
- This call takes a print record in old style (driver specific) format, and
- converts it to the format of "gxUniversalPrintRecordHdl"
- */
- {
- TPPrint poPrint; // pointer to old style print record
- gxUniversalPrintRecordHdl huPrint = hoPrint; // handle to universal print record
- gxUniversalPrintRecordPtr puPrint; // pointer to universal print record
- short qualityMode; // cached quality mode
- short wDev; // cached wDev
-
- // cache pointers for size and speed
- puPrint = *huPrint;
- poPrint = *hoPrint;
- wDev = poPrint->prStl.wDev;
-
- // determine quality mode
- if (poPrint->prJob.bJDocLoop == 0)
- qualityMode = gxDraftQuality;
- else
- {
- if (wDev & kBest)
- qualityMode = gxBestQuality;
- else
- qualityMode = gxFasterQuality;
- }
-
- // universal feed is the inverse of our feed
- puPrint->feed = 1-(poPrint->prStl.feed);
-
- // wDev 0x02 means portrait, else landscape
- if (wDev & kPortrait)
- puPrint->orientation = gxPortraitOrientation;
- else
- {
- puPrint->orientation = gxLandscapeOrientation;
-
- // landscape disabled draft, forces tall adjusted
- if (qualityMode == gxDraftQuality)
- qualityMode = gxFasterQuality;
- wDev |= kTallAdjusted;
- }
-
- // copies are in iCopies field (wow.)
- puPrint->actualCopies = poPrint->prJob.iCopies;
-
- // store our flags
- puPrint->options = 0;
-
- // tall adjusted
- if (wDev & kTallAdjusted)
- puPrint->options |= gxPreciseBitmap;
-
- // 50% reduction
- if (wDev & k50Percent)
- {
- puPrint->options |= gxUserFlag0;
- puPrint->reduction = 50;
-
- // for 50% reduction, we always return faster to the application
- qualityMode = gxFasterQuality;
- }
- else
- puPrint->reduction = 100;
-
- // no gaps
- if (wDev & kNoGaps)
- puPrint->options |= gxBiggerPages;
-
- // finally, store quality mode
- puPrint->qualityMode = qualityMode;
-
- // and we can't have any errors - because this code is too godlike.
- return(noErr);
-
- } // SD_ConvertPrintRecordTo
-
- //<FF>
- /* ---------------------------------------------------------------------------- */
- OSErr SD_ConvertPrintRecordFrom(gxUniversalPrintRecordHdl huPrint)
- /*
- This call takes a print record in universal format and converts it
- to old style (driver specific) format.
-
- Note: for the ImageWriter, I'm filling in way more things than theoretically
- I need to. However, since the ImageWriter is one of the oldest print drivers,
- there is much more of a chance that someone assumes something about one or
- more of the fields.
- */
- {
- gxUniversalPrintRecordPtr puPrint; // pointer to universal print record
- THPrint hoPrint = huPrint; // handle to old style print record
- TPPrint poPrint; // pointer to old style print record
- short options; // cached universal options
- short qualityMode; // cached universal quality mode
- short actualCopies; // cached universal copies
-
- // cache pointers for size and speed
- puPrint = *huPrint;
- poPrint = *hoPrint;
-
- // save away fields within the universal record that we'll be stomping over
- // as we convert
- options = puPrint->options;
- qualityMode = puPrint->qualityMode;
- actualCopies = puPrint->actualCopies;
-
- poPrint->iPrVersion = 4; // used to be 3, but this is
- // a new driver. We support versions
- // 3 and 4
- poPrint->prInfo.iDev = 0; // always zero for the ImageWriter
-
- // skip remaining fields in prInfo because they are unchanged
-
- // determine the wDev
- {
- short wDev;
-
- // this is the wDev value for the ImageWriter
- wDev = 0x0100;
-
- if (puPrint->orientation == gxPortraitOrientation)
- wDev |= kPortrait;
- else
- {
- // for landscape, disable draft and force tall adjusted
- if (qualityMode == gxDraftQuality)
- qualityMode = gxFasterQuality;
-
- options |= gxPreciseBitmap;
- }
-
- // user options
- if (options & gxPreciseBitmap)
- wDev |= kTallAdjusted;
- if (options & gxUserFlag0)
- {
- wDev |= k50Percent;
- qualityMode = gxFasterQuality;
- }
-
- if (options & gxBiggerPages)
- wDev |= kNoGaps;
-
- // if the application's resolution isn't 72 - then clearly SetRsl must have been called
- // to change it.
- if (poPrint->prInfo.iVRes != 72)
- {
- wDev |= kSetResCalled;
- qualityMode == gxBestQuality;
- }
-
- if (qualityMode == gxBestQuality)
- wDev |= kBest;
-
-
- // and finally, save away that short value we worked so hard to determine
- poPrint->prStl.wDev = wDev;
- }
-
- // other fields in prStl remain the same
-
- poPrint->prStl.bPort = 0;
- poPrint->prStl.feed = 1 - (puPrint->feed);
- poPrint->prInfoPT.iDev = (qualityMode == gxBestQuality) ? -768 : 0;
-
- // other fields in prInfoPT remain the same
- {
- Rect rPage = poPrint->prInfoPT.rPage;
-
- // calculate some fields we don't use - in case someone really wants to look at
- // them for some reason
- poPrint->prXInfo.iRowBytes = rPage.right >> 3;
- poPrint->prXInfo.iBandV = 32;
- poPrint->prXInfo.iBandH = poPrint->prXInfo.iRowBytes << 3;
- poPrint->prXInfo.iDevBytes = poPrint->prXInfo.iRowBytes *
- poPrint->prXInfo.iBandV +
- poPrint->prXInfo.iBandH;
- poPrint->prXInfo.iBands = (rPage.bottom+(poPrint->prXInfo.iBandV-1)) / poPrint->prXInfo.iBandV;
- poPrint->prXInfo.bPatScale = (qualityMode == gxBestQuality) ? -2 : 0;
- poPrint->prXInfo.bUlThick = 1;
- poPrint->prXInfo.bUlOffset = 1;
- poPrint->prXInfo.bUlShadow = 1;
- poPrint->prXInfo.scan = (poPrint->prStl.wDev & kPortrait) ? 0 : 2;
- poPrint->prXInfo.bXInfoX = 0;
- }
-
- // other fields in prJob remain the same
- poPrint->prJob.iCopies = actualCopies;
- poPrint->prJob.bJDocLoop = (qualityMode == gxDraftQuality) ? 0 : 1;
-
- // this routine is so studly, there can be no errors
- return(noErr);
-
- } // SD_ConvertPrintRecordFrom
-
-
- //<FF>
- /* ---------------------------------------------------------------------------- */
- OSErr SD_PrintRecordToJob(THPrint hPrint, gxJob theJob)
- /*
- We convert the "tall adjusted" setting into the correct rendering option for
- the job collection.
- */
- {
- OSErr anErr;
- Handle jobQualitySettingsHdl;
-
- anErr = Forward_GXPrintRecordToJob(hPrint, theJob);
- if (anErr == noErr)
- {
- long imagewriterOptions = kSuperRes;
-
- if ((**hPrint).prStl.wDev & kSetResCalled)
- {
- Collection jobCollection = GXGetJobCollection(GXGetJob());
- gxQualityInfo *qualitySettings;
-
-
- // get old info and replace it with final quality
-
-
- jobQualitySettingsHdl = NewHandle(0);
- anErr = MemError();
- nrequire(anErr, FailedNewHandle);
-
- anErr = GetCollectionItemHdl ( jobCollection,
- gxQualityTag,
- gxPrintingTagID,
- jobQualitySettingsHdl );
-
- if (anErr == collectionItemNotFoundErr)
- {
- Str255 bestString, roughString;
- Size count1, count2;
- Ptr p;
- short curResFile = CurResFile();
-
- UseResFile(GXGetMessageHandlerResFile());
- GetIndString( bestString, kOldQualityID, kBestString);
- GetIndString( roughString, kOldQualityID, kRoughString);
- UseResFile(curResFile);
-
- SetHandleSize(jobQualitySettingsHdl,(sizeof(gxQualityInfo) + bestString[0] + roughString[0] + 2 ));
- anErr = MemError();
- nrequire( anErr, FailedSetHandleSize );
-
- qualitySettings = *((gxQualityInfo **) jobQualitySettingsHdl);
-
- qualitySettings->disableQuality = false;
- qualitySettings->defaultQuality = 1;
- qualitySettings->currentQuality = 1;
- qualitySettings->qualityCount = 2;
-
- count1 = bestString[0]+1;
- p = qualitySettings->qualityNames;
- BlockMove( bestString, p, count1 );
-
- count2 = roughString[0]+1;
- p += count1;
- BlockMove( roughString, p, count2 );
-
- }
- else
- qualitySettings = *((gxQualityInfo **) jobQualitySettingsHdl);
-
- (qualitySettings->currentQuality = qualitySettings->qualityCount-1);
-
- anErr = AddCollectionItemHdl ( jobCollection,
- gxQualityTag,
- gxPrintingTagID,
- jobQualitySettingsHdl );
-
- if (anErr == noErr)
- (void) SetCollectionItemInfo(jobCollection, gxQualityTag, gxPrintingTagID, 0x0000FFFF, gxVolatileOutputDriverCategory);
-
- DisposHandle(jobQualitySettingsHdl);
- }
-
- if ((**hPrint).prStl.wDev & kTallAdjusted)
- imagewriterOptions = 0;
-
- if (anErr == noErr)
- anErr = AddCollectionItem(GXGetJobCollection(theJob),
- DriverCreator,
- 0,
- sizeof(imagewriterOptions),
- &imagewriterOptions);
- }
-
- FailedNewHandle:
- return(anErr);
-
- FailedSetHandleSize:
- DisposHandle(jobQualitySettingsHdl);
- return(anErr);
-
- } // SD_PrintRecordToJob
-
- //<FF>
- /* ---------------------------------------------------------------------------- */
- OSErr SD_PrValidate( THPrint hPrint, // old style print record
- Boolean *wasChanged) // was the print record changed?
- /*
- This call validates the current print record. It's fairly simplistic (as were
- all of the old drivers) - the wDev or versions don't match the current, we call
- PrintDefault. Otherwise, we call UpdatePrintRecord - to allow the driver to sanity
- check any internal fields.
-
- */
- {
- unsigned short wDev; // note: if this were signed, the shift below would fail
- Boolean recordIsInvalid = true;
- OSErr anErr = noErr;
-
- // check the wDev. The upper byte must be equal to our idea of the wDev
-
- wDev = (**hPrint).prStl.wDev;
- wDev >>= 8; // get just the device ID
-
- // If the device id is equal, then check the version number of the print record.
- // Only if that is also equal to the current version, will we return false (valid).
-
- if ( (wDev == 1)
- &&
- (
- ( ((**hPrint).iPrVersion) == 3 ) ||
- ( ((**hPrint).iPrVersion) == 4 )
- )
- )
- recordIsInvalid = false;
-
-
- // If the the print record is not valid, then return the default print record.
- // Otherwise, update the print record, based on the application's calls
- // to PrGeneral.
-
- if (recordIsInvalid)
- PrintDefault(hPrint);
- else
- anErr = UpdatePrintRecord(hPrint);
-
- *wasChanged = recordIsInvalid;
-
- return (anErr);
-
- } // SD_PrValidate
-
- //<FF>
- /* ---------------------------------------------------------------------------- */
- OSErr SD_PrJobInit(THPrint hPrint, TPPrDlg * pDlg)
- /*
- This routine is called to initialize the job dialog. We take the default
- behavior - and then disable some of the items based on settings the user
- has made:
- - 50% disables all items
- - apps that call SetRsl disable all items
- - landscape disables draft mode
- */
- {
- OSErr anErr;
-
- anErr = Forward_GXPrJobInit(hPrint, pDlg);
- if (anErr == noErr)
- {
- Boolean disableDraft = false;
- Boolean disableAll = false;
- short wDev = (**hPrint).prStl.wDev;
- short idx;
- Rect box;
- Handle item;
- short type;
-
- if (wDev & k50Percent)
- disableAll = true;
-
- if (wDev & kSetResCalled)
- disableAll = true;
-
- if (!(wDev & kPortrait))
- disableDraft = true;
-
- // disable any controls we need to
- for (idx = 6; idx <= 8; ++idx)
- {
- GetDItem((DialogPtr) *pDlg, idx, &type, &item, &box);
-
- if ( (disableAll) || ((disableDraft) && (idx == 8) ) )
- HiliteControl((ControlHandle) item, 255);
-
- }
- }
-
- return(anErr);
-
- } // SD_PrJobInit